import { isFunc, notNilEmpty } from 'qx-util';
import { GlobalHooks } from '../../core/hooks';
import { IPSAppDataEntity, IPSApplication, IPSAppView, IPSAppWF, IPSAppWFUIAction, IPSAppWFVer, IPSControlContainer, IPSDEGrid, IPSDEUIActionLogic, IPSModelObject } from '../../exports';
import { IGetModel4ModelHookTap } from '../interface';

/**
 * 订阅全局钩子
 *
 * @author chitanda
 * @date 2022-04-24 15:04:57
 * @export
 * @class GlobalTap
 * @implements {IGetModel4ModelHookTap}
 */
export class GlobalTap implements IGetModel4ModelHookTap {
  constructor() {
    GlobalHooks.getModel4.tap('GlobalTap', this.getModel4);
    GlobalHooks.getChildPSModelObject.tap('GlobalTap', this.getChildPSModelObject);
  }

  getModel4(model: IPSModelObject, cls: string, obj: IModel, tag?: string): IPSModelObject | undefined {
    // 实例化实体界面行为
    if (cls === 'app.dataentity.IPSAppDEUIAction' && obj.modelref === true) {
      // 当为实体逻辑界面行为类型节点时，取对应 dst 应用实体
      if (model.instanceof('dataentity.logic.IPSDEUIActionLogic')) {
        const entity = (model as IPSDEUIActionLogic).getDstPSAppDataEntity();
        if (entity) {
          const uiAction = entity.findPSAppDEUIAction(obj)!;
          if (uiAction) {
            return uiAction;
          }
        }
      }
    }
    // 界面行为特殊处理
    if (cls === 'view.IPSUIAction' && obj.modelref === true) {
      // 获取当前应用
      const app = model.getParentPSModelObject('app.IPSApplication') as IPSApplication;
      const entityObj = obj.getPSAppDataEntity;
      // 界面行为指定实体先从实体查找
      if (entityObj) {
        const appDataEntity = app.findPSAppDataEntity(entityObj) as IPSAppDataEntity;
        try {
          if (notNilEmpty(appDataEntity.allPSAppDEUIActions)) {
            const uiAction = appDataEntity.findPSAppDEUIAction(obj);
            if (uiAction) {
              return uiAction;
            }
          }
        } catch (error) {
          // 当行为从实体中未找到时，不报错，若从系统也未找到再报错
        }
      }
      // 工作流中获取界面行为处理
      const appWFObj = obj.getPSAppWF;
      if (appWFObj) {
        const wf = app.findPSAppWF(appWFObj) as IPSAppWF;
        const wfVersionObj = obj.getPSAppWFVer;
        if (wfVersionObj) {
          const wfVersion = wf.findPSAppWFVer(wfVersionObj) as IPSAppWFVer;
          return wfVersion.findPSAppWFUIAction(obj)!;
        }
        return wf.findPSAppWFUIAction(obj)!;
      }
      const uiAction = app.findPSAppDEUIAction(obj);
      if (uiAction) {
        return uiAction;
      }
    }
    if (cls === 'app.view.IPSAppViewUIAction' && obj.modelref === true) {
      const ctrl = model.getParentPSModelObject('control.IPSControlContainer') as IPSControlContainer;
      if (ctrl) {
        try {
          const action = ctrl.findPSAppViewUIAction(obj);
          if (action) {
            return action;
          }
        } catch (error) {
          // 先从部件容器找，未找到再从视图找
        }
      }
      const view = model.getParentPSModelObject('app.view.IPSAppView') as IPSAppView;
      const action = view.findPSAppViewUIAction(obj);
      if (action) {
        return action;
      }
    }
    if (cls === 'security.IPSSysUniRes' && obj.modelref === true && tag === 'getMapPSSysUniRes') {
      const app = model.getParentPSModelObject('app.IPSApplication') as IPSApplication;
      const opPriv = app.allPSDEOPPrivs?.find(item => {
        if (item.mapSysUniRes && item.mapSysUniResCode === obj.id) {
          return true;
        }
        return false;
      });
      if (opPriv) {
        return opPriv;
      }
    }
    // 所有查找应用实体熟悉的，全部去应用实体获取
    if (cls === 'app.dataentity.IPSAppDEField' && tag === 'getPSAppDEField') {
      const entity = model.getParentPSModelObject('app.dataentity.IPSAppDataEntity') as IPSAppDataEntity;
      if (entity) {
        const deField = entity.findPSAppDEField(obj);
        if (deField) {
          return deField;
        }
      }
    }
    // 表格更新项查找
    if (cls === 'control.grid.IPSDEGridEditItemUpdate' && obj.modelref === true) {
      const grid = model.getParentPSModelObject('control.grid.IPSDEGrid') as IPSDEGrid;
      const update = grid.findPSDEGridEditItemUpdate(obj);
      if (update) {
        return update;
      }
    }
    return undefined;
  }

  getChildPSModelObject(model: IPSModelObject, cls: string, obj: IModel, tag?: string): IPSModelObject | undefined {
    return undefined;
  }

  /**
   * 查找父，父下拥有指定方法。例如: 查找拥有 getPSAppViewUIActions, getParentModelByFunc(model, 'getPSAppViewUIActions')。返回拥有 getPSAppViewUIActions 方法的父
   *
   * @author chitanda
   * @date 2022-10-20 11:10:15
   * @protected
   * @param {IPSModelObject} modelObject
   * @param {string} funcTag
   * @return {*}  {(IPSModelObject | IPSModelObject[] | null)}
   */
  protected getParentModelByFunc(modelObject: IPSModelObject, funcTag: string): IPSModelObject | IPSModelObject[] | null {
    if (!modelObject) {
      throw new Error(`父对象无效，查找方法: ${funcTag}`);
    }
    const fn = (modelObject as any)[funcTag];
    if (isFunc(fn)) {
      return modelObject;
    }
    const t = modelObject.getParentPSModelObject();
    if (t) {
      return this.getParentModelByFunc(t, funcTag);
    }
    return null;
  }
}
